<?php

namespace app\common\logic;

use app\common\enum\CrontabEnum;
use app\common\model\Crontab;
use Throwable;

class CrontabLogic extends BaseLogic
{
    /**
     * 执行定时任务
     * @param $id
     * @return void
     */
    public function run($id): void
    {
        $info = Crontab::find($id);

        $params = $info->params;
        if (!empty($params)) {
            $arr = json_decode($params, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                Crontab::where('id', $id)->update([
                    'error' => '参数不是json字符串',
                    'status' => CrontabEnum::ERROR,
                ]);
                return;
            }
            $params = $arr;
        } else {
            $params = [];
        }

        // 开始执行
        $startTime = microtime(true);

        switch ($info->type) {
            case 1:
                // 类任务
                $class_name = $info->command;
                $method_name = 'run';
                $class = new $class_name;
                if (method_exists($class, $method_name)) {
                    try {
                        $class->$method_name($params);
                        // 清除错误信息
                        Crontab::where('id', $id)->update(['error' => '']);
                    } catch (Throwable $e) {
                        Crontab::where('id', $id)->update([
                            'error' => $e->getMessage(),
                            'status' => CrontabEnum::ERROR,
                        ]);
                    } finally {
                        $endTime = microtime(true);
                        // 本次执行时间
                        $useTime = round(($endTime - $startTime), 2);
                        $maxTime = max($useTime, $info->max_time);

                        Crontab::where('id', $id)->update([
                            'last_time' => time(),
                            'time' => $useTime,
                            'max_time' => $maxTime
                        ]);
                    }
                } else {
                    Crontab::where('id', $id)->update([
                        'error' => '类:' . $class_name . ',方法:run,未找到',
                        'status' => CrontabEnum::ERROR,
                    ]);
                }
        }
    }
}
